Serverless FrameworkでAngularアプリをAWS S3にデプロイ

やりたいこと

  • AWS S3にAngularアプリを静的WEBホスティングする。
  • CloudFrontでHTTPS通信&高速化する。
  • 開発環境やステージング環境など、複数の環境へのデプロイを簡単に切り替えたい。
  • 上記作業をServerless Frameworkを使って自動化する。
  • 独自ドメインは......設定出来るけど、今回は除外。
    別記事にしました。


前提

  • AWSアカウントを持っている。
  • デプロイに必要な権限を持ったAWS IAMユーザのアクセスキー・シークレットアクセスキーを持っている。
  • Angularアプリを作成済。(Angularである必要性はないです)

 

システム構成

Serverless + Angular + S3でのシステム構成





 



Serverless Frameworkをインストール

$ npm install serverless
$ npm install serverless-single-page-app-plugin
$ npm install serverless-cloudfront-invalidate


Serverless Frameworkのバージョン

この記事で使用しているServerless Frameworkのバージョンです。

serverless:2.52.0
serverless-cloudfront-invalidate:1.9.0
serverless-single-page-app-plugin:1.0.2


serverless.ymlを作成

下記内容の serverless.yml を作成してプロジェクトのルートディレクトリに配置します。

service: angular-test-app

frameworkVersion: '2'

plugins:
  - serverless-single-page-app-plugin
  - serverless-cloudfront-invalidate

provider:
  name: aws
  stage: ${env:STAGE}
  region: ap-northeast-1
  stackName: ${self:service}-${self:provider.stage}
  environment:
    stage: ${self:provider.stage}

custom:
  s3Bucket: ${self:service}-deploy-${self:provider.stage}
  # angular.jsonのoutputPathに注意(この記事ではdist直下にビルドファイルを出力する設定をしています)
  s3LocalPath: dist/
  cloudfrontInvalidate:
    - distributionIdKey: CDNDistributionId
      autoInvalidate: true
      items:
        - '/*'

resources:
  Resources:
    WebAppS3Bucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.s3Bucket}
        AccessControl: PublicRead
        WebsiteConfiguration:
          IndexDocument: index.html
          ErrorDocument: index.html

    WebAppS3BucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket:
          Ref: WebAppS3Bucket
        PolicyDocument:
          Statement:
            - Sid: PublicReadGetObject
              Effect: Allow
              Principal: "*"
              Action:
                - s3:GetObject
              Resource:
                Fn::Join: ["", ["arn:aws:s3:::", { "Ref": "WebAppS3Bucket" }, "/*"]]

    WebAppCloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - DomainName:
                Fn::Join: ["", [{ "Ref": "WebAppS3Bucket" }, ".s3-ap-northeast-1.amazonaws.com"]]
              Id: WebApp
              CustomOriginConfig:
                HTTPPort: 80
                HTTPSPort: 443
                OriginProtocolPolicy: https-only
          PriceClass: PriceClass_200
          Enabled: 'true'
          DefaultRootObject: index.html
          CustomErrorResponses:
            - ErrorCode: 404
              ResponseCode: 200
              ResponsePagePath: /index.html
            - ErrorCode: 403
              ResponseCode: 200
              ResponsePagePath: /index.html
          DefaultCacheBehavior:
            AllowedMethods:
              - DELETE
              - GET
              - HEAD
              - OPTIONS
              - PATCH
              - POST
              - PUT
            TargetOriginId: WebApp
            ForwardedValues:
              QueryString: 'false'
              Cookies:
                Forward: none
            ViewerProtocolPolicy: https-only

  Outputs:
    WebAppS3BucketOutput:
      Value:
        'Ref': WebAppS3Bucket
    CDNDistributionId:
      Description: CDN distribution id.
      Value:
        Ref: WebAppCloudFrontDistribution


ビルド&デプロイ

# 環境変数の設定
## 任意のステージ名
$ export STAGE=dev
## デプロイ権限を持ったIAMユーザのアクセスキー&シークレットアクセスキー
$ export AWS_ACCESS_KEY_ID=XXX
$ export AWS_SECRET_ACCESS_KEY=XXX

# ビルド
$ npx ng build --prod

# デプロイ
$ npx sls deploy -v -s $STAGE
$ npx sls syncToS3 -v -s $STAGE


デプロイしたページを確認

ブラウザで https://ドメイン名 を開くとデプロイしたページを開くことができます。
※初回デプロイ時は開けるようになるまで時間がかかります。

ドメイン名はAWSのコンソール画面からCloudFrontのページを開くと確認できます。


次回

今回スルーした独自ドメインの設定をします。

https://d-oshige.blogspot.com/2021/11/serverless--s3-angular-02.html